#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>

void *thread_worker1(void *args);
void *thread_worker2(void *args);

//把需要传的变量都丢到结构体里，因为创建线程的时候只能传一个变量
typedef struct worker_ctx_s  
{
	int					shared_var;
	pthread_mutex_t		lock;
}worker_ctx_t;


int main(int argc, char **argv)
{
	worker_ctx_t		worker_ctx;
	pthread_t			tid;	//线程id
	pthread_attr_t		thread_attr;	//线程属性

	worker_ctx.shared_var = 1000;
	pthread_mutex_init(&worker_ctx.lock, NULL);		//初始化互斥锁

	//属性
	if( pthread_attr_init(&thread_attr) )	//调用init函数对其初始化
	{
		printf("pthread_attr_init() failure: %s\n", strerror(errno));
		return -1;
	}

	if( pthread_attr_setstacksize(&thread_attr, 120*1024) )		//设置栈大小
	{
		printf("pthread_attr_setstacksize() failure: %S\n", strerror(errno));
		return -1;
	}

	if(  pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) )		//设置分离
	{
		printf("pthread_attr_setdetachstate() failure: %s\n", strerror(errno));
		return -1;
	}

	//创建线程
	pthread_create(&tid, &thread_attr, thread_worker1, &worker_ctx);	//第一个线程加载属性，默认分离状态
	printf("Thread worker1 tid[%ld] created ok\n", tid);

	pthread_create(&tid, NULL, thread_worker2, &worker_ctx);	//第二个线程没有设置属性，默认会合状态
	printf("thread worker2 tid[%ld] created ok\n", tid);

	pthread_attr_destroy(&thread_attr);		//前面用了init初始化，用完要摧毁

	pthread_join(tid, NULL);	//会合状态主线程要等，阻塞，直到thread_worker2退出(exit())
	//任何地方只要调用exit()进程退出，所以子线程不能调用exit()函数，exit()是进程退出



	while(1)		//主线程不能退出
	{
		printf("Main/Control thread shared_var: %d\n", worker_ctx.shared_var);
		sleep(10);
	}

}

void *thread_worker1(void *args)
{
	worker_ctx_t		*ctx = (worker_ctx_t *)args;

	if( !args )
	{
		printf("%s() get invalid arguments\n", __FUNCTION__);
		pthread_exit(NULL);		//线程退出
	}

	printf("Thread worker1 [%ld] start running...\n", pthread_self());		//查看线程号

	while(1)
	{
		pthread_mutex_lock(&ctx->lock);		//上锁——阻塞锁，如果第二个进程在上锁，就等直到第二个进程释放锁

		printf("+++: %s before shared_var++: %d\n", __FUNCTION__, ctx->shared_var);
		ctx->shared_var += 1;
		sleep(2);
		printf("+++: %s after sleep shared_var: %d\n", __FUNCTION__, ctx->shared_var);

		pthread_mutex_unlock(&ctx->lock);	//释放锁

		sleep(1);
	}

	printf("Thread worker1 exit...\n");

	return NULL;
}

void *thread_worker2(void *args)
{
	worker_ctx_t        *ctx = (worker_ctx_t *)args;

	if( !args )
	{
		printf("%s() get invalid arguments\n", __FUNCTION__);
		pthread_exit(NULL);
	}

	printf("Thread worker2 [%ld] start running...\n", pthread_self());

	while(1)
	{
		if(0 != pthread_mutex_trylock(&ctx->lock))		//上锁——非阻塞锁，第一个线程上锁，第二个进程接着运行
		{
			continue;
		}

		printf("---: %s before shared_var++: %d\n", __FUNCTION__, ctx->shared_var);
		ctx->shared_var += 1;
		sleep(2);
		printf("---:%s after sleep shared_var: %d \n",__FUNCTION__, ctx->shared_var);
	
		pthread_mutex_unlock(&ctx->lock);

		sleep(1);
	}

	printf("thread worker2 exit...\n");

	return NULL;
}
